package jmind.asteroidea.plugin.spring;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.context.expression.MapAccessor;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.List;
import java.util.concurrent.ConcurrentMap;

/**
 * description:
 *
 * @author weibo.xie
 * @date:2022/7/8 下午2:37
 */
public class SpelExpression {
    private static SpelExpression instance=new SpelExpression();
    public static SpelExpression getInstance(){
        return instance;
    }
    private final ExpressionParser parser ;
    private final ConcurrentMap<String, Expression> expressionMap ;
    private SpelExpression(){
        parser = new SpelExpressionParser();
        expressionMap = Maps.newConcurrentMap();
    }

    public final Expression getExpression(String spel) {
        Expression expression = expressionMap.get(spel);
        if (expression == null) {
             expression = parser.parseExpression(spel);
            expressionMap.put(spel, expression);
        }
        return expression;
    }

    public Object parseValue(String spel, String[] names,Object[] values){
        Expression expression = getExpression(spel);
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.addPropertyAccessor(new MapAccessor());
        for (int i = 0; i < names.length; i++) {
            context.setVariable(names[i], values[i]);
        }
        return expression.getValue(context);
    }

    public List<Object> parseValues(String[] tags, String[] names, Object[] values){
        StandardEvaluationContext context = new StandardEvaluationContext();
        /**
         * https://www.jianshu.com/p/b53965977d26
         * 设置允许map可以使用 . 的形式。
         * 不设置 使用 map['key'] 的形式
         * 设置 可以使用 map.key 的形式
         */
        context.addPropertyAccessor(new MapAccessor());
        for (int i = 0; i < names.length; i++) {
            context.setVariable(names[i], values[i]);
        }
        List<Object> lists= Lists.newArrayList();
        for(String spel:tags){
            lists.add(getExpression(spel).getValue(context));
        }
        return lists;
    }




}
